package com.bincloud.vue.admin.common.util;

import com.bincloud.vue.admin.common.exception.BaseException;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.regex.Pattern;

/**
 * @Description: 图片工具类
 * @Author: bincloud, mvpzhou
 * @Date: Create By bincloud, mvpzhou on 2022/2/20
 */
@SuppressWarnings("unused")
public class ImageUtils {
    private ImageUtils() {}

    private static final String FONT_DEFAULT = "Default";
    private static final String PNG = "png";
    private static final String DATA_IMAGE_PNG = "data:image/png;base64,";

    private static final int DRAW_X_CN = 19;
    private static final int DRAW_Y_CN = 156;
    private static final int DRAW_X_EN = 50;
    private static final int DRAW_Y_EN = 156;

    /**
     * 生成头像图片流 根据字符串 英文 数字
     *
     * @param word 头像字符 长度 1
     * @return 图片流
     */
    public static byte[] avatar(String word) {
        if (word == null || word.length() != 1) {
            throw new BaseException("只支持1个字符");
        }
        if (Pattern.matches("^[\u4E00-\u9FA5]+$", word)) {
            return avatarCN(word);
        } else if (Pattern.matches("[a-zA-Z0-9]", word)) {
            return avatarEN(word);
        }
        throw new BaseException("字符不符合生成规则");
    }

    /**
     * 生成头像图片流 根据字符串 英文 数字
     *
     * @param word 头像字符 长度 1
     * @return 图片流
     */
    public static byte[] avatarEN(String word) {
        return avatarXY(word, DRAW_X_EN, DRAW_Y_EN);
    }

    /**
     * 生成头像图片流 根据字符串 中文
     *
     * @param word 头像字符 长度 1
     * @return 图片流 中文
     */
    public static byte[] avatarCN(String word) {
        return avatarXY(word, DRAW_X_CN, DRAW_Y_CN);
    }

    /**
     * 生成头像图片流 根据字符串 中文
     *
     * @param word 头像字符 长度 1
     * @param drawX 字符 x 起始点
     * @param drawY 字符 y 起始点
     * @return 图片流 中文
     */
    public static byte[] avatarXY(String word, int drawX, int drawY) {
        try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            Font font = new Font(FONT_DEFAULT, Font.BOLD, 160);
            BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
            Graphics2D graphics = bi.createGraphics();
            graphics.setColor(new Color(255, 255, 255));
            graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            graphics.fillRoundRect(0, 0, 200, 200, 200, 200);
            graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
            graphics.setColor(new Color(68, 138, 138));
            graphics.setFont(font);
            graphics.drawString(word, drawX, drawY);
            ImageIO.write(bi, PNG, bos);
            return bos.toByteArray();
        } catch (Exception e) {
            throw new BaseException("头像生成异常");
        }
    }

    /**
     * 图片流转 Base64 String Png
     *
     * @param bytes 文件流
     * @return Base64 String
     */
    public static String convertBase64String(byte[] bytes) {
        Base64.Encoder encoder = Base64.getEncoder();
        return DATA_IMAGE_PNG + encoder.encodeToString(bytes);
    }

    /**
     * 图片流转 Base64 String
     *
     * @param bytes 文件流
     * @return Base64 String
     */
    public static String convertBase64(byte[] bytes) {
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(bytes);
    }

    /**
     * Base64 String 转 图片流
     *
     * @param str Base64 String
     * @return 文件流
     */
    public static byte[] convertBytes(String str) {
        Base64.Decoder decoder = Base64.getDecoder();
        return decoder.decode(str);
    }
}
